package com.google.code.task;

import java.util.Map;

class AsyncerTaskProcessor implements Runnable {
  private TaskAndEvent taskAndEvent;
  private Map<Object,Object> contextMap;

  AsyncerTaskProcessor(Task task, TaskEvent event, Map<Object,Object> contextMap) {
    this(new TaskAndEvent(task, event), contextMap);
  }

  AsyncerTaskProcessor(TaskAndEvent taskAndEvent, Map<Object,Object> contextMap) {
    checkNull(taskAndEvent);
    this.taskAndEvent = taskAndEvent;
    this.contextMap = contextMap;
  }

  public void run() {
    TaskContext.putLocalMap(contextMap);
    doStartedEvent(taskAndEvent);
    TaskResultType taskResult = doTask(taskAndEvent);
    doTaskCompletedEvent(taskAndEvent, taskResult);
  }

  void checkNull(TaskAndEvent taskAndEvent) {
    if (taskAndEvent == null) {
      throw new NullPointerException("TaskAndEvent object can`be null.");
    }
  }

  void doTaskCompletedEvent(TaskAndEvent taskAndEvent, TaskResultType taskResult) {
    if (taskAndEvent == null) {
      return;
    }
    if (taskAndEvent.isThereEvent()) {
      taskAndEvent.getEvent().taskCompleted(taskResult);
    }
  }

  TaskResultType doTask(TaskAndEvent taskAndEvent) {
    if (taskAndEvent == null) {
      return null;
    }

    TaskResultType taskResult = taskAndEvent.getTask().execute();
    return taskResult;
  }

  void doStartedEvent(TaskAndEvent taskAndEvent) {
    if (taskAndEvent == null) {
      return;
    }
    if (taskAndEvent.isThereEvent()) {
      taskAndEvent.getEvent().taskStarted();
    }
  }
}
